from .telegram_bot import bot
# from db.db_storage import DataUsage
from db.db_operations import DataOperations
from .telegram_supplementary import (develop_basic_input, 
                                    check_user_chat, 
                                    develop_output_tasks,
                                    develop_output_user_type,
                                    develop_output_moving_tasks,
                                    develop_output_user_subtype,
                                    develop_grouping_showings,
                                    develop_input_user_statistics,
                                    develop_user_settings_frequency,
                                    develop_output_tasks_change_type,
                                    develop_input_user_settings,
                                    return_message_greetings,
                                    return_message_info_type,
                                    return_message_info_subtype,
                                    develop_output_tasks_unknown,
                                    develop_output_tasks_type_subtype,
                                    develop_output_tasks_update_frequency)
from config import (content_react_basic,
                    Callbacks,
                    AdditionalMessages,
                    GroupingTasksMenu, 
                    TelegramCommands, 
                    ButtonsInput)


markup_values = develop_basic_input()
database_connection = DataOperations()
notifications = database_connection.return_notifications_variations()


@bot.message_handler(commands=[TelegramCommands.start])
def make_start_bot(message):
    """
    Function to make the start bot value
    Input:  message = message which was previously developed to it
    Output: we developed values of it
    """
    value_bool = check_user_chat(message.chat.id)
    if not value_bool:
        return
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    bot.send_message(message.chat.id, return_message_greetings(), reply_markup=markup_values)
    
@bot.message_handler(commands=[TelegramCommands.menu])
def make_menu_user(message):
    """
    Function to make menu of the selected 
    Input:  message = message which was previously developed in the supplementary
    Output: we developed message for the 
    """
    value_bool = check_user_chat(message.chat.id)
    if not value_bool:
        return
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    bot.send_message(message.chat.id, return_message_greetings(True), reply_markup=markup_values)

@bot.message_handler(commands=[TelegramCommands.support])
def make_support_user(message):
    """
    Function which is dedicated to return the possibility to support developers for it
    Input:  message = message of the user
    Output: support menu for the developers
    """
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    bot.send_message(message.chat.id, "We didn't provide this feature yet", reply_markup=markup_values)

@bot.message_handler(commands=[TelegramCommands.characteristics])
def make_characteristics_user(message):
    """
    Function which is dedicated to return the characteristics of the task
    Input:  message = message of the user
    Output: support menu for the developers
    """
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    bot.send_message(message.chat.id, 
                    GroupingTasksMenu.text_show_statistics,
                    reply_markup=develop_input_user_statistics(
                        database_connection.make_basic_statistics(
                            message.chat.id)
                        )
                    )

@bot.message_handler(commands=[TelegramCommands.add_types])
def make_add_types_user(message):
    """
    Function which is dedicated to add new types for the user
    Input:  message = message of the selected user
    Output: we inserted for the user new type
    """
    value_text_new = message.text[len(f"/{TelegramCommands.add_types}"):].strip()
    if not value_text_new:
        return
    value_text_new = database_connection.insert_values_user_type(message.chat.id, value_text_new)
    bot.send_message(message.chat.id, 
        f"You developed new type with name `{value_text_new}`", 
        parse_mode='Markdown')

@bot.message_handler(commands=[TelegramCommands.add_subtypes])
def make_add_subtypes_user(message):
    """
    Function which is dedicated to add new subtypes for the user
    Input:  message = message of the selected user
    Output: we inserted for the user new subtype
    """
    value_text_new = message.text[len(f"/{TelegramCommands.add_subtypes}"):].strip()
    if not value_text_new:
        return
    value_text_new = database_connection.insert_values_user_subtype(message.chat.id, value_text_new)
    bot.send_message(message.chat.id, 
        f"You developed new subtype with name `{value_text_new}`", 
        parse_mode='Markdown')
    
@bot.message_handler(commands=[TelegramCommands.help])
def make_help_user(message):
    """
    Function which is develop to make personal testing values
    Input:  message = message which was previously developed
    Output: we developed values for the checkings
    """
    value_bool = check_user_chat(message.chat.id)
    if not value_bool:
        return
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    # print(message)
    # print('<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<')
    # database_connection.make_basic_testing()
    bot.send_message(message.chat.id, "We didn't provide this feature yet", reply_markup=markup_values)

@bot.message_handler(commands=[TelegramCommands.settings])
def make_settings_user(message):
    """
    Function which is about development 
    Input:  message = message which was previously developed
    Output: settings values of the modules
    """
    value_bool = check_user_chat(message.chat.id)
    if not value_bool:
        return
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    bot.send_message(
        message.chat.id, 
        GroupingTasksMenu.text_show_setting, 
        reply_markup=develop_input_user_settings(
            database_connection.return_info_settings(message.chat.id),
            message.chat.id,
            0))

@bot.message_handler(commands=[TelegramCommands.tasks])
def make_task_user(message):
    """
    Function which is dedicated to show user all his/her tasks
    Input:  message = message value from the telegram
    Output: list of the tasks of it
    """
    if not check_user_chat(message.chat.id):
        return
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    
    def_types, def_subtypes, def_tasks = \
        database_connection.return_info_settings(message.chat.id)[:3]
    value_check = develop_grouping_showings(def_types, def_subtypes, def_tasks)
    
    if value_check == 1:
        id_count_type, id_name_type = \
            database_connection.return_values_tasks_group_menu(message.chat.id)
        bot.send_message(chat_id=message.chat.id, 
            text=GroupingTasksMenu.text_group_types, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_type, 
                id_name_type, 
                Callbacks.callback_types_selection,
                Callbacks.callback_show_next_types,
                3,
                9,
                0))
    
    if value_check == 2:
        id_count_subtype, id_name_subtype = \
            database_connection.return_values_tasks_subgroup_menu(message.chat.id)
        bot.send_message(chat_id=message.chat.id, 
            text=GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_subtype, 
                id_name_subtype, 
                Callbacks.callback_subtypes_selection,
                Callbacks.callback_show_next_subtypes,
                2,
                8,
                0))
    
    elif value_check == 3:
        id_count_task, id_name_task = \
            database_connection.return_values_tasks_menu(message.chat.id)
        bot.send_message(chat_id=message.chat.id, 
            text=GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_task, 
                id_name_task,
                Callbacks.callback_task_selection,
                ' ',
                1))
    
    elif value_check == 4:
        bot.send_message(chat_id=message.chat.id, 
            text=GroupingTasksMenu.text_select_unkwown, 
            reply_markup=develop_output_tasks_unknown(message.chat.id))
    
@bot.message_handler(commands=[TelegramCommands.types])
def make_types_user(message):
    """
    Function which is dedicated to get the full calculation of the user groups
    Input:  message = message information which user previously sent
    Output: we created full interaction of it
    """
    if not check_user_chat(message.chat.id):
        return
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    bot.send_message(chat_id=message.chat.id, 
            text=GroupingTasksMenu.text_show_types_user, 
            reply_markup=develop_output_user_type(
                message.chat.id, 
                database_connection.return_values_types_user(
                    message.chat.id),
                0))

@bot.message_handler(commands=[TelegramCommands.subtypes])
def make_subtypes_user(message):
    """
    Function which is dedicated to get the full calculation of the user subgroups    
    Input:  message = message information which user previously sent
    Output: we created full interaction which groups
    """
    if not check_user_chat(message.chat.id):
        return
    database_connection.insert_values_user(message.message_id, message.chat.id, 
            message.chat.first_name, message.chat.last_name, message.chat.username)
    bot.send_message(chat_id=message.chat.id, 
            text=GroupingTasksMenu.text_show_subtypes_user, 
            reply_markup=develop_output_user_subtype(
                message.chat.id, 
                database_connection.return_values_subtypes_user(
                    message.chat.id),
                0))

def make_user_task_update_description(message) -> None:
    """
    Function which is dedicated to update the description of it
    Input:  message = message which is used of it
    Output: we updated the description of selected task
    """
    update_desc = message.reply_to_message
    if not update_desc.reply_markup:
        return
    if update_desc.reply_markup and update_desc.json.get('text', '') != GroupingTasksMenu.text_group_task:
        return
    data = \
        update_desc.json.get('reply_markup', {}).get('inline_keyboard', [[{}]])[0][0].get('callback_data', '')
    _, id_task, id_accept, id_user = data.split('_')
    id_accept, id_user = int(id_accept), int(id_user)
    if id_accept == 1:
        database_connection.update_task_description_start(id_task, id_user, message.text)
        bot.send_message(id_user, 
                        f'We updated start description of your task to `{message.text}`',
                        parse_mode='Markdown')
    else: 
        database_connection.update_task_description_finish(id_task, id_user, message.text)
        bot.send_message(id_user, 
                        f'We updated finish description of your task to `{message.text}`',
                        parse_mode='Markdown')

def manage_user_task(message) -> None:
    """
    Function which is dedicated to produce values of the user tasks
    Input:  message = message value of the insertion of it
    Output: message was previously developed for the 
    """
    database_connection.insert_values_default_tasks(message.chat.id, message.id, False)
    bot.send_message(message.chat.id,
                    'We developed `new task by this message`', 
                    reply_to_message_id=message.id, 
                    parse_mode='Markdown')
    
@bot.message_handler(content_types=content_react_basic)
def manage_user_task_content(message) -> None:
    """
    Fucntion which is dedicated to react on selected messages
    Input:  message = message of the various type which was developed
    Output: we saved the message which was previously developed
    """
    manage_user_task(message)

@bot.callback_query_handler(func=lambda call: True)
def calculate_text_operations(query) -> None:
    """
    Function which is dedicated to develop values of the test operations
    Input:  query = message value of it; buttons activity reaction
    Output: developed value of it
    """
    data = query.data
    if not check_user_chat(query.message.chat.id):
        return
    
    database_connection.insert_values_user(query.message.message_id, query.message.chat.id, 
            query.message.chat.first_name, query.message.chat.last_name, query.message.chat.username)
    
    if data == Callbacks.callback_empty:
        return
    
    elif data == Callbacks.callback_settings:
        bot.send_message(
        query.message.chat.id, 
        GroupingTasksMenu.text_show_setting, 
        reply_markup=develop_input_user_settings(
            database_connection.return_info_settings(query.message.chat.id),
            query.message.chat.id,
            0))

    elif data == Callbacks.callback_subtypes_group:
        id_count_subtype, id_name_subtype = \
            database_connection.return_values_tasks_subgroup_menu(query.message.chat.id)
        bot.send_message(chat_id=query.message.chat.id, 
            text=GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_subtype, 
                id_name_subtype, 
                Callbacks.callback_subtypes_selection,
                Callbacks.callback_show_next_subtypes,
                2,
                8,
                0))

    elif data == Callbacks.callback_types_group:
        id_count_type, id_name_type = \
            database_connection.return_values_tasks_group_menu(query.message.chat.id)
        bot.send_message(chat_id=query.message.chat.id, 
            text=GroupingTasksMenu.text_group_types, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_type, 
                id_name_type, 
                Callbacks.callback_types_selection,
                Callbacks.callback_show_next_types,
                3,
                9,
                0))

    elif data == Callbacks.callback_task_group:
        id_count_task, id_name_task = \
            database_connection.return_values_tasks_menu(query.message.chat.id)
        bot.send_message(chat_id=query.message.chat.id, 
            text=GroupingTasksMenu.text_group_task_by, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_task, 
                id_name_task,
                Callbacks.callback_task_selection,
                ' ',
                1))
    
    elif data.split('_')[0] == Callbacks.callback_select_all:
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_basic(query.message.chat.id, 0)
        value_menu = develop_output_tasks(query.message.chat.id, 
            tasks_proccessing, tasks_expired, tasks_finished)
        bot.send_message(chat_id=query.message.chat.id, 
            text=GroupingTasksMenu.text_group_subtypes,
            reply_markup=value_menu)
    
    elif data.split('_')[0] == Callbacks.callback_update_types:
        _, user_id, index = data.split('_')
        user_id, index = int(user_id), int(index)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_user_type(
                query.message.chat.id, 
                database_connection.return_values_types_user(
                    query.message.chat.id),
                index))
    
    elif data.split('_')[0] == Callbacks.callback_update_subtypes:
        _, user_id, index = data.split('_')
        user_id, index = int(user_id), int(index)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_user_subtype(
                query.message.chat.id, 
                database_connection.return_values_subtypes_user(
                    query.message.chat.id),
                index))
    
    elif data.split('_')[0] == Callbacks.callback_info_types:
        _, user_id, type_id = data.split('_')
        user_id, type_id = int(user_id), int(type_id)
        type_main, type_default, type_processing, type_expired, type_finished, \
            type_subtype = database_connection.return_values_type_description(user_id, type_id)
        text, reply_markup = return_message_info_type(user_id, type_main, type_default, type_processing, \
            type_expired, type_finished, type_subtype)
        bot.send_message(chat_id=query.message.chat.id, 
            text=text,
            parse_mode='Markdown',
            reply_markup=reply_markup) 

    elif data.split('_')[0] == Callbacks.callback_info_subtypes:
        _, user_id, subtype_id = data.split('_')
        user_id, subtype_id = int(user_id), int(subtype_id)
        subtype_main, subtype_default, subtype_processing, subtype_expired, subtype_finished, \
            subtype_type = database_connection.return_values_subtype_description(user_id, subtype_id)
        text, reply_markup = return_message_info_subtype(user_id, subtype_main, subtype_default, \
            subtype_processing, subtype_expired, subtype_finished, subtype_type)
        bot.send_message(chat_id=query.message.chat.id, 
            text=text,
            parse_mode='Markdown',
            reply_markup=reply_markup) 
        
    elif data.split('_')[0] == Callbacks.callback_show_tasks_by_types:
        _, user_id, type_id = data.split('_')
        user_id, type_id = int(user_id), int(type_id)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_by_types(user_id, type_id, 0, True)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, tasks_finished, 
            0,
            1, 
            f"{Callbacks.callback_next_task_group_types}_{type_id}")

        if value_menu:
            bot.send_message(chat_id=query.message.chat.id, 
                text=GroupingTasksMenu.text_group_types,
                reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_show_tasks_by_subtypes:
        _, user_id, subtype_id = data.split('_')
        user_id, subtype_id = int(user_id), int(subtype_id)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_by_subtypes(user_id, subtype_id, 0, True)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, 
            tasks_finished, 
            0, 
            1,
            f"{Callbacks.callback_next_task_group_subtypes}_{subtype_id}")

        if value_menu:
            bot.send_message(chat_id=query.message.chat.id, 
                text=GroupingTasksMenu.text_group_subtypes,
                reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_show_next_types:
        _, index = data.split('_')
        index = int(index)
        id_count_type, id_name_type = \
            database_connection.return_values_tasks_group_menu(query.message.chat.id)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_types, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_type, 
                id_name_type, 
                Callbacks.callback_types_selection,
                Callbacks.callback_show_next_types,
                3,
                9,
                index))
    
    elif data.split('_')[0] == Callbacks.callback_show_next_subtypes:
        _, index = data.split('_')
        index = int(index)
        id_count_subtype, id_name_subtype = \
            database_connection.return_values_tasks_subgroup_menu(query.message.chat.id)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_subtype, 
                id_name_subtype, 
                Callbacks.callback_subtypes_selection,
                Callbacks.callback_show_next_subtypes,
                2,
                8,
                index))
    
    elif data.split('_')[0] == Callbacks.callback_task_selection:
        _, sort_id = data.split('_')
        sort_id = int(sort_id)
        if sort_id == 1:
            desc = GroupingTasksMenu.expired_task_desc_processing
        elif sort_id == 2:
            desc = GroupingTasksMenu.expired_task_desc_expired
        elif sort_id == 3:
            desc = GroupingTasksMenu.expired_task_desc_finished
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_basic(query.message.chat.id, sort_id, False)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, 
            tasks_finished, 
            0, 
            1,
            f"{Callbacks.callback_next_task_group_tasks}_{sort_id}")

        if value_menu:
            bot.send_message(
                chat_id=query.message.chat.id, 
                text=desc,
                reply_markup=value_menu)
    
    elif data.split('_')[0] == Callbacks.callback_types_selection:
        _, type_id = data.split('_')
        type_id = int(type_id)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_by_types(query.message.chat.id, type_id, 0, True)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, 
            tasks_finished, 
            0, 
            1,
            f"{Callbacks.callback_next_task_group_types}_{type_id}")

        if value_menu:
            bot.send_message(
                chat_id=query.message.chat.id, 
                text=GroupingTasksMenu.text_group_task,
                reply_markup=value_menu)
    
    elif data.split('_')[0] == Callbacks.callback_subtypes_selection:
        _, subtype_id = data.split('_')
        subtype_id = int(subtype_id)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_by_subtypes(query.message.chat.id, subtype_id, 0, True)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, 
            tasks_finished, 
            0, 
            1,
            f"{Callbacks.callback_next_task_group_subtypes}_{subtype_id}")

        if value_menu:
            bot.send_message(
                chat_id=query.message.chat.id, 
                text=GroupingTasksMenu.text_group_task,
                reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_remove_user_type:
        _, type_id, index, user_id = data.split('_')
        index, user_id = int(index), int(user_id)
        if user_id != query.message.chat.id:
            return
        database_connection.change_all_tasks_types(type_id)
        database_connection.delete_user_type(query.message.chat.id, type_id)
        database_connection.remove_subtypes_types_by_user(type_id)
        database_connection.remove_types_removed_by_user(type_id)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_types_user, 
            reply_markup=develop_output_user_type(
                query.message.chat.id, 
                database_connection.return_values_types_user(
                    query.message.chat.id),
                index))
        #TODO return values of the sending message that we removed

    elif data.split('_')[0] == Callbacks.callback_remove_user_subtype:
        _, subtype_id, index, user_id = data.split('_')
        index, user_id = int(index), int(user_id)
        if user_id != query.message.chat.id:
            return
        database_connection.change_all_tasks_subtypes(subtype_id)
        database_connection.delete_user_subtype(query.message.chat.id, subtype_id)
        database_connection.remove_types_subtypes_by_user(subtype_id)
        database_connection.remove_subtypes_removed_by_user(subtype_id)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_user_subtype(
                query.message.chat.id, 
                database_connection.return_values_subtypes_user(
                    query.message.chat.id),
                index))
        #TODO return values of the subtypes messaging

    elif data.split('_')[0] == Callbacks.callback_task_make_done:
        _, task_id, task_index, check, *callback_new, id_user = data.split('_')
        task_id, task_index, check, id_user = int(task_id), int(task_index), int(check), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.make_change_tasks_types(task_id, query.message.chat.id, 1, 3)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_basic(query.message.chat.id, 0, check)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, 
            tasks_finished, 
            task_index, 
            check, 
            '_'.join(callback_new))

        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_task_change_frequency:
        _, task_id, not_id, _, id_user = data.split('_')
        not_id, id_user = int(not_id), int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.send_message(
            query.message.chat.id,
            GroupingTasksMenu.text_change_frequency, #TODO change tasks
            reply_markup=develop_output_tasks_update_frequency(
                notifications,
                query.message.chat.id,
                task_id,
                not_id,
                0
            )
        )

    elif data.split('_')[0] == Callbacks.callback_update_tasks_frequency:
        _, task_id, not_id, not_id_new, index, id_user = data.split('_')
        not_id, not_id_new, index, id_user = int(not_id), int(not_id_new), int(index), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_values_task_notification(task_id, not_id, not_id_new)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, #TODO change text
            reply_markup=develop_output_tasks_update_frequency(
                notifications,
                query.message.chat.id,
                task_id,
                not_id_new,
                index
                )
            )

    elif data.split('_')[0] == Callbacks.callback_update_tasks_frequency_next:
        _, index, task_id, not_id, id_user = data.split('_')
        index, not_id, id_user = int(index), int(not_id), int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=develop_output_tasks_update_frequency(
                notifications,
                query.message.chat.id,
                task_id,
                not_id,
                index
                )
            )

    elif data.split('_')[0] == Callbacks.callback_task_add_timing:
        _, task_id, _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        value_add_timing = database_connection.return_info_settings(id_user)[6]
        date_old, date_new = database_connection.update_task_datetime(
            task_id, 
            id_user, 
            value_add_timing)
        bot.send_message(id_user,
            f"We changed the task estimated time on {value_add_timing} days."\
            f"\nBefore: `{date_old}`\nAfter: `{date_new}`", parse_mode='Markdown')

    elif data.split('_')[0] == Callbacks.callback_update_tasks_alarm:
        _, id_task, index, id_type, check, id_user = data.split('_')
        index, id_type, check, id_user = int(index), int(id_type), int(check), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_values_task_notification_datetime(id_task, query.message.chat.id, id_type)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_basic(query.message.chat.id, 0, check)
        value_menu = develop_output_tasks(query.message.chat.id, 
            tasks_proccessing, tasks_expired, tasks_finished, index, check)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_task_make_unexpired:
        _, task_id, task_index, check, *callback_new, id_user = data.split('_')
        task_id, task_index, check, id_user = int(task_id), int(task_index), int(check), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.make_change_tasks_types(task_id, query.message.chat.id, 2, 1)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_basic(query.message.chat.id, 0, check)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, 
            tasks_finished, 
            task_index, 
            check, 
            '_'.join(callback_new))
            
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_task_make_repeat:
        _, task_id, task_index, check, *callback_new, id_user = data.split('_')
        task_id, task_index, check, id_user = int(task_id), int(task_index), int(check), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.make_change_tasks_types(task_id, query.message.chat.id, 3, 1)
        tasks_proccessing, tasks_expired, tasks_finished = \
            database_connection.return_tasks_basic(query.message.chat.id, 0, check)
        value_menu = develop_output_tasks(
            query.message.chat.id, 
            tasks_proccessing, 
            tasks_expired, 
            tasks_finished, 
            task_index, 
            check, 
            '_'.join(callback_new))
        
        if value_menu:
            bot.edit_message_reply_markup(
                query.message.chat.id, 
                query.message.id,
                GroupingTasksMenu.text_group_task, 
                reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_show_next_task:
        _, index, check, user_id, *callback_new = data.split('_')
        index, check, user_id = int(index), int(check), int(user_id)
        
        if user_id != query.message.chat.id:
            return
        
        if callback_new[0] == Callbacks.callback_empty:
            tasks_proccessing, tasks_expired, tasks_finished = \
                database_connection.return_tasks_basic(query.message.chat.id, 0, check)
        
        elif callback_new[0] == Callbacks.callback_next_task_group_tasks:
            tasks_proccessing, tasks_expired, tasks_finished = \
                database_connection.return_tasks_basic(query.message.chat.id, int(callback_new[1]), False)
        
        elif callback_new[0] == Callbacks.callback_next_task_group_types:
            tasks_proccessing, tasks_expired, tasks_finished = \
                database_connection.return_tasks_by_types(query.message.chat.id, int(callback_new[1]), 0, True)
        
        elif callback_new[0] == Callbacks.callback_next_task_group_subtypes:
            tasks_proccessing, tasks_expired, tasks_finished = \
                database_connection.return_tasks_by_subtypes(query.message.chat.id, int(callback_new[1]), 0, True)
        
        value_menu = develop_output_tasks(query.message.chat.id, 
            tasks_proccessing, tasks_expired, tasks_finished, index, check, '_'.join(callback_new))
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=value_menu)

    elif data.split('_')[0] == Callbacks.callback_info_tasks:
        _, id_task, id_accept, id_user = data.split('_')
        id_accept, id_user = int(id_accept), int(id_user)
        if id_user != query.message.chat.id:
            return
        msg_print, msg_reply = database_connection.return_info_task(id_task, id_user, id_accept)
        bot.send_message(id_user, msg_print, reply_to_message_id=msg_reply, parse_mode='Markdown')

    elif data.split('_')[0] == Callbacks.callback_task_change_type:
        _, id_task, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.send_message(id_user, GroupingTasksMenu.text_change_task_type, 
                reply_markup=develop_output_tasks_change_type(
                database_connection.return_type_user_change(id_user),
                database_connection.return_type_task(id_task),
                id_user,
                id_task,
                0,
                True)
            )
    
    elif data.split('_')[0] == Callbacks.callback_task_change_subtype:
        _, id_task, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.send_message(id_user, GroupingTasksMenu.text_change_task_subtype, 
                reply_markup=develop_output_tasks_change_type(
                database_connection.return_subtype_user_change(id_user),
                database_connection.return_subtype_task(id_task),
                id_user,
                id_task,
                0,
                False)
            )

    elif data.split('_')[0] == Callbacks.callback_task_new_type_next:
        _, id_task, index, id_user = data.split('_')
        index, id_user = int(index), int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=develop_output_tasks_change_type(
                database_connection.return_type_user_change(id_user),
                database_connection.return_type_task(id_task),
                id_user,
                id_task,
                index,
                True)
            )
    
    elif data.split('_')[0] == Callbacks.callback_task_new_subtype_next:
        _, id_task, index, id_user = data.split('_')
        index, id_user = int(index), int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=develop_output_tasks_change_type(
                database_connection.return_subtype_user_change(id_user),
                database_connection.return_subtype_task(id_task),
                id_user,
                id_task,
                index,
                False)
            )

    elif data.split('_')[0] == Callbacks.callback_task_new_type:
        _, id_task, id_type_new, id_type_old, index, id_user = data.split('_')
        id_user, index = int(id_user), int(index)
        if id_user != query.message.chat.id:
            return
        database_connection.update_type_task(id_task, id_type_old, id_type_new)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=develop_output_tasks_change_type(
                database_connection.return_type_user_change(id_user),
                database_connection.return_type_task(id_task),
                id_user,
                id_task,
                index,
                True)
            )
        
    elif data.split('_')[0] == Callbacks.callback_task_new_subtype:
        _, id_task, id_subtype_new, id_subtype_old, index, id_user = data.split('_')
        id_user, index = int(id_user), int(index)
        if id_user != query.message.chat.id:
            return
        database_connection.update_subtype_task(id_task, id_subtype_old, id_subtype_new)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_group_task, 
            reply_markup=develop_output_tasks_change_type(
                database_connection.return_subtype_user_change(id_user),
                database_connection.return_subtype_task(id_task),
                id_user,
                id_task,
                index,
                False)
            )

    elif data.split('_')[0] == Callbacks.callback_move_task_by_types:
        _, id_type, id_user = data.split('_')
        id_type, id_user = int(id_type), int(id_user)
        if id_user != query.message.chat.id:
            return
        if database_connection.select_count_moving_tasks_type(id_user, id_type):
            bot.send_message(id_user, 
                GroupingTasksMenu.text_move_all_subtype_to_another, 
                reply_markup=develop_output_moving_tasks(
                database_connection.return_type_user_change(id_user),
                id_type,
                id_user,
                True,
                0
            ))

    elif data.split('_')[0] == Callbacks.callback_move_task_by_subtypes:
        _, id_subtype, id_user = data.split('_')
        id_subtype, id_user = int(id_subtype), int(id_user)
        if id_user != query.message.chat.id:
            return
        if database_connection.select_count_moving_tasks_subtype(id_user, id_subtype):
            bot.send_message(id_user, 
                GroupingTasksMenu.text_move_all_subtype_to_another, 
                reply_markup=develop_output_moving_tasks(
                database_connection.return_subtype_user_change(id_user),
                id_subtype,
                id_user,
                False,
                0
            ))
    
    elif data.split('_')[0] == Callbacks.callback_find_move_task_types:
        _, id_type, id_type_new, index, id_user = data.split('_')
        id_type_new, index, id_user = int(id_type_new), int(index), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.change_all_tasks_types(id_type, id_type_new)
        bot.edit_message_reply_markup(
            query.message.chat.id,
            query.message.id,
            GroupingTasksMenu.text_move_all_type_to_another,
            reply_markup=develop_output_moving_tasks(
                database_connection.return_type_user_change(id_user),
                id_type_new,
                id_user,
                True,
                index
            ))
    
    elif data.split('_')[0] == Callbacks.callback_find_move_task_subtypes:
        _, id_subtype, id_subtype_new, index, id_user = data.split('_')
        id_subtype_new, index, id_user = int(id_subtype_new), int(index), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.change_all_tasks_subtypes(id_subtype, id_subtype_new)
        bot.edit_message_reply_markup(
            query.message.chat.id,
            query.message.id,
            GroupingTasksMenu.text_move_all_type_to_another,
            reply_markup=develop_output_moving_tasks(
                database_connection.return_type_user_change(id_user),
                id_subtype_new,
                id_user,
                False,
                index
            ))

    elif data.split('_')[0] == Callbacks.callback_next_move_task_types:
        _, index, id_type, id_user = data.split('_')
        index, id_type, id_user = int(index), int(id_type), int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.edit_message_reply_markup(
            query.message.chat.id,
            query.message.id,
            GroupingTasksMenu.text_move_all_type_to_another,
            reply_markup=develop_output_moving_tasks(
                database_connection.return_type_user_change(id_user),
                id_type,
                id_user,
                True,
                index
            ))

    elif data.split('_')[0] == Callbacks.callback_next_move_task_subtypes:
        _, index, id_subtype, id_user = data.split('_')
        index, id_subtype, id_user = int(index), int(id_subtype), int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.edit_message_reply_markup(
            query.message.chat.id,
            query.message.id,
            GroupingTasksMenu.text_move_all_subtype_to_another,
            reply_markup=develop_output_moving_tasks(
                database_connection.return_subtype_user_change(id_user),
                id_subtype,
                id_user,
                False,
                index
            ))

    elif data.split('_')[0] == Callbacks.callback_settings_next:
        _, id_user, index = data.split('_')
        id_user, index = int(id_user), int(index)
        if id_user != query.message.chat.id:
            return
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                index))
    
    elif data.split('_')[0] == Callbacks.callback_settings_change_frequency:
        _, id_frequency, id_user = data.split('_')
        id_frequency, id_user = int(id_frequency), int(id_user)
        if id_user != query.message.chat.id:
            return
        bot.send_message(
            query.message.chat.id, 
            GroupingTasksMenu.text_change_frequency_default, 
            reply_markup=develop_user_settings_frequency(
                notifications,
                id_frequency,
                id_user))
    
    elif data.split('_')[0] == Callbacks.callback_settings_new_frequency:
        _, id_frequency_new, id_frequency, id_user = data.split('_')
        id_frequency_new, id_user = int(id_frequency_new), int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_frequency(id_user, id_frequency_new)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_change_frequency_default, 
            reply_markup=develop_user_settings_frequency(
                notifications,
                id_frequency_new,
                id_user))
        bot.send_message(
            query.message.chat.id,
            GroupingTasksMenu.text_updated_default_frequency,
            reply_markup=markup_values)

    elif data.split('_')[0] == Callbacks.callback_settings_group_types:
        _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_grouping(id_user, 1)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                0))

    elif data.split('_')[0] == Callbacks.callback_settings_group_subtypes:
        _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_grouping(id_user, 2)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                0))
    
    elif data.split('_')[0] == Callbacks.callback_settings_group_task:
        _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_grouping(id_user, 3)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                0))

    elif data.split('_')[0] == Callbacks.callback_settings_group_default:
        _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_grouping(id_user, 4)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                0))
    
    elif data.split('_')[0] == Callbacks.callback_types_default:
        _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_grouping(id_user, 1)
        id_count_type, id_name_type = \
            database_connection.return_values_tasks_group_menu(query.message.chat.id)
        bot.send_message(chat_id=query.message.chat.id, 
            text=GroupingTasksMenu.text_group_types, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_type, 
                id_name_type, 
                Callbacks.callback_types_selection,
                Callbacks.callback_show_next_types,
                3,
                9,
                0))

    elif data.split('_')[0] == Callbacks.callback_subtypes_default:
        _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_grouping(id_user, 2)
        id_count_subtype, id_name_subtype = \
            database_connection.return_values_tasks_subgroup_menu(query.message.chat.id)
        bot.send_message(chat_id=query.message.chat.id, 
            text=GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_subtype, 
                id_name_subtype, 
                Callbacks.callback_subtypes_selection,
                Callbacks.callback_show_next_subtypes,
                2,
                8,
                0))

    elif data.split('_')[0] == Callbacks.callback_task_default:
        _, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_grouping(id_user, 3)
        id_count_task, id_name_task = \
            database_connection.return_values_tasks_menu(query.message.chat.id)
        bot.send_message(chat_id=query.message.chat.id, 
            text=GroupingTasksMenu.text_group_subtypes, 
            reply_markup=develop_output_tasks_type_subtype(
                id_count_task, 
                id_name_task,
                Callbacks.callback_task_selection,
                ' ',
                1))
    
    elif data.split('_')[0] == Callbacks.callback_settings_change_add_timing:
        _, number_new, id_user = data.split('_')
        id_user = int(id_user)
        if id_user != query.message.chat.id:
            return
        database_connection.update_default_add_timing(number_new, id_user)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                1))

    elif data.split('_')[0] == Callbacks.callback_settings_change_showings:
        _, type_bool, type_id, id_user = data.split('_')
        type_bool, type_id, id_user = int(type_bool), int(type_id), int(id_user)
        if id_user != query.message.chat.id:
            return
        type_bool = False if type_bool else True
        database_connection.update_default_tasks_showings(id_user, type_id, type_bool)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                0))

    elif data.split('_')[0] == Callbacks.callback_settings_change_datetime_not:
        _, type_bool, type_id, id_user = data.split('_')
        type_bool, type_id, id_user = int(type_bool), int(type_id), int(id_user)
        type_bool = False if type_bool else True
        database_connection.update_default_tasks_datetime(id_user, type_id, type_bool)
        bot.edit_message_reply_markup(
            query.message.chat.id, 
            query.message.id,
            GroupingTasksMenu.text_show_setting, 
            reply_markup=develop_input_user_settings(
                database_connection.return_info_settings(query.message.chat.id),
                query.message.chat.id,
                1))

@bot.message_handler(content_types=["text"])
def develop_message_user(message):
    """
    Function which is dedicated on reacting on your text
    Input:  message = message which is user sent to you
    Output: we developed values of all commands
    """
    value_bool = check_user_chat(message.chat.id)
    if not value_bool:
        return

    if message.text == ButtonsInput.button_tasks:
        bot.send_message(
            message.chat.id, 
            AdditionalMessages.menu_tasks, 
            reply_markup=markup_values)
        make_task_user(message)

    if message.text == ButtonsInput.button_settings:
        bot.send_message(
            message.chat.id,
            AdditionalMessages.menu_settings, 
            reply_markup=markup_values)
        make_settings_user(message)
    
    if message.text == ButtonsInput.button_types:
        bot.send_message(
            message.chat.id, 
            AdditionalMessages.menu_types, 
            reply_markup=markup_values)
        make_types_user(message)

    if message.text == ButtonsInput.button_subtypes:
        bot.send_message(
            message.chat.id, 
            AdditionalMessages.menu_subtypes, 
            reply_markup=markup_values)
        make_subtypes_user(message)

    if message.text == ButtonsInput.button_support:
        make_support_user(message)

    if message.text == ButtonsInput.button_characteristics:
        bot.send_message(
            message.chat.id, 
            AdditionalMessages.menu_characteristics, 
            reply_markup=markup_values)
        make_characteristics_user(message)

    if message.text == ButtonsInput.button_help:
        make_help_user(message)

    if message.reply_to_message:
        make_user_task_update_description(message)
    elif message.text in [ButtonsInput.button_tasks, 
                        ButtonsInput.button_types, 
                        ButtonsInput.button_subtypes,
                        ButtonsInput.button_characteristics,
                        ButtonsInput.button_help,
                        ButtonsInput.button_settings,
                        ButtonsInput.button_support]:
        return
    elif not message.reply_to_message and message.chat.id == message.from_user.id:
        manage_user_task(message)